<template>
  <div class="exhcange-products-list-component-page">
    <div class="block">
      <header>
        <h2 class="required">
          <slot />
        </h2>
      </header>
      <section style="height:400px;display:flex;flex-direction:column;">
        <el-row class="block-item">
          <el-col :span="12">
            <!-- <div>&nbsp;</div> -->
            <el-button type="primary" @click="onOpenImportProduct"
              >模板导入产品</el-button
            >
            <el-divider direction="vertical" />
            <el-button type="text" @click="onGetProductTemplate"
              >模板下载</el-button
            >
          </el-col>
          <el-col :span="12" class="right">
            <el-button type="primary" @click="onOpenProductDialog"
              >添加新换产品</el-button
            >
          </el-col>
        </el-row>
        <el-editable
          :columns="SELECTED_PRODUCTS_COLUMNS"
          :payload="payload_products"
          :need-pagination="true"
          height="200"
          @reload="reloadData"
        >
          <!-- <template v-slot:default-stockCount="{ row, $index }">
            <div>
              <el-input-number
                v-model="row.referencePrice"
                :step="1"
                :precision="2"
                size="small"
                :min="0.0"
                :max="99999999.99"
                @change="onChangeReferencePrice(row, $index)"
              />
            </div>
          </template> -->
          <template #default-index="{ $index }">
            {{ $index + 1 }}
          </template>
          <template #default-exhcangeCount="{ row }">
            <div>
              <el-input-number
                v-model="row.productCount"
                :step="1"
                step-strictly
                size="small"
                :min="1"
                :max="
                  Number(row.optionalQuantity) -
                    Number(row.selectedQuantity) +
                    Number(row.productCount)
                "
                @change="onChangeCount(row)"
              />
              <span style="margin-left:10px;color:red;"
                >可换量{{ calcOptionalNum(row) | decimalToInteger }}</span
              >
            </div>
          </template>
          <template #default-opt="{ row, $index }">
            <a href="javascript:;" @click="onDeleteProduct(row, $index)"
              >移除</a
            >
          </template>
          <!-- 给创建报台用的表格内表单 -->
        </el-editable>
      </section>
    </div>
    <upload
      ref="upload"
      :params="stepOneFormData"
      @complete="getUploadProducts"
    />
  </div>
</template>

<script>
import ElEditable from '@components/el-editable';
import { urlDownload } from '@const/utils';
import { uniqBy } from 'lodash';
import { computeRate, formatPrice } from '@const/filter';
// eslint-disable-next-line import/named
import { ProductAddDialogService } from './product-dialog/product-add.dialog.module';
// eslint-disable-next-line import/extensions
import * as CONSTS from './index.const.js';
// eslint-disable-next-line import/extensions
import { IndexService } from './index.service.js';
// eslint-disable-next-line import/extensions
import upload from './upload';

const service = new IndexService();
export default {
  components: {
    ElEditable,
    upload
  },
  filters: {
    decimalToInteger(num) {
      return Number(num);
    }
  },
  inject: ['exTemplateDownLoad'],
  props: {
    stepOneFormData: {
      type: Object
    },
    products: {
      type: Array
    },
    type: {
      type: String,
      default: 'default'
    },
    operationType: String,
    title: String
  },
  data() {
    return {
      ...CONSTS,
      productsItem: [],
      payload_products: {},
      pager: {
        number: 1,
        size: 20
      },
      // 由于更新数量的动态性，下标的切换要同步。故这样搞
      index: {
        start: 1,
        end: 1
      }
    };
  },
  computed: {
    productAddDialogService() {
      return new ProductAddDialogService(this.$axios, this.$store, {
        type: this.type
      });
    }
  },
  watch: {
    products: {
      handler(val) {
        if (val !== undefined) {
          this.productsItem = val;
          let startIndex = null;
          let endIndex = null;
          startIndex = (this.pager.number - 1) * this.pager.size;
          endIndex = this.pager.number * this.pager.size;
          this.payload_products = service.getPayload(
            this.productsItem,
            this.pager,
            startIndex,
            endIndex
          );
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    calcOptionalNum(row) {
      return Number(row.optionalQuantity) - Number(row.selectedQuantity) < 0
        ? 0
        : Number(row.optionalQuantity) - Number(row.selectedQuantity);
    },
    getUploadProducts(payload) {
      const loadProductList = payload;
      if (loadProductList.length > 0) {
        this.updateProductData(payload, true);
      }
    },
    // 前端分页逻辑
    reloadData(pager) {
      const startIndex = (pager.number - 1) * pager.size;
      const endIndex = pager.number * pager.size;
      this.payload_products = service.getPayload(
        this.productsItem,
        pager,
        startIndex,
        endIndex
      );
      this.pager = pager;
    },
    onDeleteProduct(row, index) {
      const startIndex = (this.pager.number - 1) * this.pager.size;
      const endIndex = this.pager.number * this.pager.size;
      this.productsItem.splice(startIndex + index, 1);
      // 在这里重新计算selectedQuantity
      this.calcQuantity(row);
      this.payload_products = service.getPayload(
        this.productsItem,
        this.pager,
        startIndex,
        endIndex
      );
      if (this.payload_products.content.length === 0) {
        // 如果当前获取的内容为空，那么要重新获取一下数据
        this.pager.number -= 1;
        if (this.pager.number <= 0) this.pager.number = 1;
        // eslint-disable-next-line no-shadow
        const startIndex = (this.pager.number - 1) * this.pager.size;
        // eslint-disable-next-line no-shadow
        const endIndex = this.pager.number * this.pager.size;
        this.payload_products = service.getPayload(
          this.productsItem,
          this.pager,
          startIndex,
          endIndex
        );
      }
      this.$emit('update:products', this.productsItem);
    },
    onChangeCount(row) {
      const newRow = row;
      if (!newRow.productCount) {
        this.$nextTick(() => {
          newRow.productCount = 1;
        });
      }
      this.calcCurTotalFee(row);
      this.calcQuantity(row);

      console.log(this.productsItem, 'this.productsItem');
      this.$emit('update:products', this.productsItem);
    },
    calcQuantity(row) {
      const coProductNameNums = this.productsItem
        .filter(item => item.productName === row.productName)
        .reduce((total, item) => total + item.productCount, 0);
      this.productsItem.forEach(item => {
        const newItem = item;
        if (newItem.productName === row.productName) {
          newItem.selectedQuantity = coProductNameNums;
        }
      });
    },
    onChangeReferencePrice(row) {
      this.calcCurTotalFee(row);
    },
    calcCurTotalFee(row) {
      const newRow = row;
      newRow.totalFee = formatPrice(
        computeRate(row.referencePrice, row.productCount),
        2
      );
    },
    onOpenProductDialog() {
      // 这里的formData传递完整的数据，再在子组件内整理成子级组件想要的数据格式，
      // 实际上这样做是“不好的”，但是由于数据的复杂度和混乱度，故此选择。
      // 再有一个原因是，产品搜索列表还需要一些额外的参数
      this.productAddDialogService
        .create({
          title: '添加新换产品',
          query: {
            operationType: this.operationType,
            formData: this.stepOneFormData
          },
          confirmButtonClickHandler: (data = {}) => {
            // data.forEach(element => {
            //   this.$set(element, 'productCount', 1);
            //   this.$set(element, 'totalFee', formatPrice(computeRate(element.referencePrice, element.productCount), 2));
            // });
            this.updateProductData(data);
          }
        })
        .mount();
    },
    updateProductData(data, isImport) {
      if (isImport) {
        // data.forEach(element => {
        //   this.$set(element, 'productCount', 1);
        //   this.$set(element, 'totalFee', formatPrice(computeRate(element.referencePrice, element.productCount), 2));
        // });
        this.productsItem = service.reConcatSelectData(
          data,
          [],
          'mixsIds',
          isImport
        );
        const returnGoodsCurNums = this.concatCommonNameProduct(
          this.stepOneFormData.return_goods,
          'productCount'
        );
        // 初始化可选数量
        returnGoodsCurNums.forEach(rGood => {
          this.productsItem.forEach(item => {
            if (item.productName === rGood.name) {
              this.$set(item, 'optionalQuantity', rGood.commonNameTotalNum);
            }
          });
        });
      } else {
        console.log(data, 'data-------data');
        console.log(this.productsItem, 'this.productsItem-------------');
        this.productsItem = service.reConcatSelectData(
          data,
          this.productsItem,
          'mixsIds',
          isImport
        );
      }
      let startIndex = null;
      let endIndex = null;
      startIndex = (this.pager.number - 1) * this.pager.size;
      endIndex = this.pager.number * this.pager.size;
      this.payload_products = service.getPayload(
        this.productsItem,
        this.pager,
        startIndex,
        endIndex
      );
      // 通过退货产品全部数据，与新换产品的全部数据做数据逻辑计算
      // 更新后重新计算最终的结果数据，给selectedQuantity赋值
      const uniqStorageArr = this.concatCommonNameProduct(
        this.productsItem,
        'productCount'
      );
      uniqStorageArr.forEach(it => {
        this.productsItem.forEach(item => {
          const newItem = item;
          if (it.name === newItem.productName) {
            newItem.selectedQuantity = it.commonNameTotalNum;
          }
        });
      });
      console.log(this.productsItem, 'productsItem--------');
      this.$emit('update:products', this.productsItem);
    },
    // 一旦数据更改（也即数据的增删），就要进行重新的内部逻辑运算。“逻辑运算”特指产品的业务需求。
    // 同名产品的合并方法，返回一个对应数组，内容是产品名称及其对应的数量
    concatCommonNameProduct(products, numKey) {
      if (!products.length) return [];
      // 第一步，通过退货产品，计算出，同名产品的总“退货量”
      // 先获取到去重后的产品名称有哪些
      const uniqProductsNames = uniqBy(products, 'productName').map(
        item => item.productName
      );
      // 然后，我们形成一个下面这样结构的数组，记录上一步已选同名产品的总“退货量”
      const curProductNameTotalNumsArr = [];
      uniqProductsNames.forEach(name => {
        const obj = {
          name: '',
          commonNameTotalNum: 0
        };
        products.forEach(item => {
          obj.name = name;
          if (name === item.productName) {
            obj.commonNameTotalNum += item[numKey];
          }
        });
        curProductNameTotalNumsArr.push(obj);
      });
      return curProductNameTotalNumsArr;
    },
    onOpenImportProduct() {
      console.log(this.stepOneFormData, 'stepOneFormData');
      if (
        this.stepOneFormData.exchange_goods &&
        this.stepOneFormData.exchange_goods.length > 0
      ) {
        this.$confirm(
          '模板导入将会清空列表新换产品',
          '确定模板导入新换产品？',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }
        )
          .then(() => {
            this.$refs.upload.dialog_visible = true;
            this.$emit('update:products', []);
          })
          .catch(() => {
            this.$message({
              type: 'info',
              message: '已取消模板导入'
            });
          });
      } else {
        this.$refs.upload.dialog_visible = true;
      }
    },
    onGetProductTemplate() {
      urlDownload(this.exTemplateDownLoad);
    }
  }
};
</script>
